#include <avr/io.h>
#include <util/delay.h>

#include "ewlcd.h"
#include "ardew.h"

static uint8_t lcdpins[11];

void lcd_setup(uint8_t crs
               , uint8_t crw
               , uint8_t ce
               , uint8_t cd0
               , uint8_t cd1
               , uint8_t cd2
               , uint8_t cd3
               , uint8_t cd4
               , uint8_t cd5
               , uint8_t cd6
               , uint8_t cd7) {
  lcdpins[RS] = crs;
  lcdpins[RW] = crw;
  lcdpins[ENABLE] = ce;
  lcdpins[D0] = cd0;
  lcdpins[D1] = cd1;
  lcdpins[D2] = cd2;
  lcdpins[D3] = cd3;
  lcdpins[D4] = cd4;
  lcdpins[D5] = cd5;
  lcdpins[D6] = cd6;
  lcdpins[D7] = cd7;
  for (int i=0; i<=11; i++) {
    pinoff(lcdpins[i]);
  }
}

void lcd_transmit() {
  pinon(ENABLE);
  _delay_ms(1);
  pinoff(ENABLE);
  _delay_ms(1);
}

void lcd_clear() {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinoff(lcdpins[D5]);
  pinoff(lcdpins[D4]);
  pinoff(lcdpins[D3]);
  pinoff(lcdpins[D2]);
  pinoff(lcdpins[D1]);
  pinon(lcdpins[D0]);
  lcd_transmit();
}

void lcd_home() {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinoff(lcdpins[D5]);
  pinoff(lcdpins[D4]);
  pinoff(lcdpins[D3]);
  pinoff(lcdpins[D2]);
  pinon(lcdpins[D1]);
  lcd_transmit();
}

void lcd_entrymode(uint8_t cursorincdec, uint8_t dispshift) {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinoff(lcdpins[D5]);
  pinoff(lcdpins[D4]);
  pinoff(lcdpins[D3]);
  pinon(lcdpins[D2]);
  if (cursorincdec) { pinon(lcdpins[D1]); } else { pinoff(lcdpins[D1]); }
  if (dispshift) { pinon(lcdpins[D0]); } else { pinoff(lcdpins[D0]); }
  lcd_transmit();
}

void lcd_setdisplay(uint8_t dispon, uint8_t cursoron, uint8_t blinkon) {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinoff(lcdpins[D5]);
  pinoff(lcdpins[D4]);
  pinon(lcdpins[D3]);
  if (dispon) { pinon(lcdpins[D2]); } else { pinoff(lcdpins[D2]); }
  if (cursoron) { pinon(lcdpins[D1]); } else { pinoff(lcdpins[D1]); }
  if (blinkon) { pinon(lcdpins[D0]); } else { pinoff(lcdpins[D0]); }
  lcd_transmit();
}

void lcd_shift(uint8_t dispshift, uint8_t rightshift) {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinoff(lcdpins[D5]);
  pinon(lcdpins[D4]);
  if (dispshift) { pinon(lcdpins[D3]); } else { pinoff(lcdpins[D3]); }
  if (rightshift) { pinon(lcdpins[D2]); } else { pinoff(lcdpins[D2]); }
  lcd_transmit();
}

void lcd_setfunction(uint8_t bits8, uint8_t lines2, uint8_t dots10) {
  pinoff(lcdpins[RS]);
  pinoff(lcdpins[D7]);
  pinoff(lcdpins[D6]);
  pinon(lcdpins[D5]);
  if (bits8) { pinon(lcdpins[D4]); } else { pinoff(lcdpins[D4]); }
  if (lines2) { pinon(lcdpins[D3]); } else { pinoff(lcdpins[D3]); }
  if (dots10) { pinon(lcdpins[D2]); } else { pinoff(lcdpins[D2]); }
  lcd_transmit();
}

void lcd_putc(uint8_t c) {
  uint8_t i;
  for (i=0; i<8; i++) {
    if (c & (1 << i)) {
      pinon(lcdpins[D0 + i]);
    } else {
      pinoff(lcdpins[D0 + i]);
    }
  }
  pinon(lcdpins[RS]);
  lcd_transmit();
}

void lcd_puts(uint8_t* s) {
}
